<?php
namespace Wx\Model;
use Think\Model;
/**
 * 在线支付异步通知
 */
class OnlinePayModel extends Model {
    private $POSTDATA;
    public $notify;
    public function __construct(){

        vendor('WxPayPubHelper.WxPayPubHelper');
        parent::__construct();
        $this->logPath = "data/".strftime("%Y-%m-%d",time())."-wxpay.log";
        $this->logPathStatus = 1;
        $config = M('Payments')->field('payName,payConfig')->where(array('payCode' => 'weixin', 'enabled' => 1))->find();
        $payConfig = json_decode($config['payConfig']);
        $this->notify = new \Notify_pub($payConfig->appId, $payConfig->mchId, $payConfig->apiKey, $payConfig->appsecret);
    }
    

    //支付宝异步通知处理
    public function aliNotify(){
        if ($_POST['trade_status'] == 'TRADE_SUCCESS') {
            $out_trade_no = $_POST['out_trade_no'];      //商户订单号
            $trade_no = $_POST['trade_no'];          //支付宝交易号
            $trade_status = $_POST['trade_status'];      //交易状态
            $total_fee = $_POST['total_fee'];         //交易金额
            $notify_id = $_POST['notify_id'];         //通知校验ID。
            $notify_time = $_POST['notify_time'];       //通知的发送时间。格式为yyyy-MM-dd HH:mm:ss。
            $buyer_email = $_POST['buyer_email'];       //买家支付宝帐号；
            $parameter = array(
                "out_trade_no" => $out_trade_no, //商户订单编号；
                "transaction_id" => $trade_no,     //支付宝交易号；
                "total_fee" => $total_fee*100,    //交易金额；
                "trade_status" => $trade_status, //交易状态
               // "transaction_id" => $notify_id,    //通知校验ID。
                "time_end" => $notify_time,  //通知的发送时间。
                "openid" => $buyer_email,  //买家支付宝帐号；
                "payType"=>1
            );
            $this->POSTDATA=$parameter;
            $this->actionData();
        }
    }

    
    //微信异步通知处理
    public function wxNotify(){
        $xml = $GLOBALS['HTTP_RAW_POST_DATA'];
//         $xml = '<xml><appid><![CDATA[wxa45354e69c2e01f9]]></appid>
// <bank_type><![CDATA[CFT]]></bank_type>
// <cash_fee><![CDATA[1]]></cash_fee>
// <fee_type><![CDATA[CNY]]></fee_type>
// <is_subscribe><![CDATA[N]]></is_subscribe>
// <mch_id><![CDATA[1236763602]]></mch_id>
// <nonce_str><![CDATA[5zxvhsw6kzfwdtc7z3qme0rb7ym7f9ha]]></nonce_str>
// <openid><![CDATA[okZhjuFoa-ggiZs4Iuv_LPtLgTcM]]></openid>
// <out_trade_no><![CDATA[wx_1_100001876_1500459520]]></out_trade_no>
// <result_code><![CDATA[SUCCESS]]></result_code>
// <return_code><![CDATA[SUCCESS]]></return_code>
// <sign><![CDATA[5DFBCE0C3B7CBE560BB5B12C70F770AD]]></sign>
// <time_end><![CDATA[20170719181845]]></time_end>
// <total_fee>1</total_fee>
// <trade_type><![CDATA[JSAPI]]></trade_type>
// <transaction_id><![CDATA[4002752001201707191596385879]]></transaction_id>
// </xml>';
        file_put_contents('huidiaoTest',  $xml,FILE_APPEND);
        if($xml===null){
            $this->log_result($this->logPath,'[非微信异步通知请求]');
        }else{
            $this->notify->saveData($xml);
            $this->POSTDATA = $this->notify->data;
        }
        if($this->notify->checkSign() === TRUE){
            $this->checkResultCode($this->notify);
            $this->log_result($this->logPath,'[签名通过]');
        }elseif ($this->notify->checkSign() === FALSE){
            $this->log_result($this->logPath,'[签名失败]');
            return;
        }else{
            return;
        }
    }

    private function checkResultCode($notify){
        if ($notify->data["return_code"] == "SUCCESS") {
            $this->actionData();
            $this->log_result($this->logPath,"【通信标识return_code】:".$notify->data["return_code"]);
            $this->log_result($this->logPath,"【通信标识return_msg】:".$notify->data["return_msg"]);
        }
        else {
            $this->log_result($this->logPath,"【通信标识return_code】:".$notify->data["return_code"]);
            $this->log_result($this->logPath,"【通信标识return_msg】:".$notify->data["return_msg"]);
        }
    }

    private function actionData(){
        $out_trade_no_text=$this->POSTDATA['out_trade_no'];
        $this->log_result($this->logPath,"【out_trade_no】:".$out_trade_no_text);
        //$out_trade_no_text 'wx_'.$type . $id . '_' . $payConfig->appId;
        $temp=explode('_', $out_trade_no_text);
        $out_trade_no=$temp[2];
        $this->log_result($this->logPath,"【out_trade_no】:".$out_trade_no);
        //判断是订单付款还是充值
        $type=$temp[1];
        $this->log_result($this->logPath,"【判断是1订单付款2充值】:".$type);
        // dump($type);
        switch ($type){
            case 1:
                $this->log_result($this->logPath,"【进入订单付款");
                $this->addOrder($out_trade_no);
                break;
            case 2:
                $this->log_result($this->logPath,"【进入钱充值流程");
                $this->addMoney($out_trade_no);
                break;
            default:
                break;
        }
    }


    private function addOrder($out_trade_no){
         // dump($out_trade_no);

        M()->startTrans ();
        $orderInfo=M('orders')->where(array('orderId'=>$out_trade_no))->find();
// dump($orderInfo);
// dump($orderInfo['orderStatus']);
// dump($orderInfo['userId']);
        if(!$orderInfo){
            $this->log_result($this->logPath,"【订单不存在】".$out_trade_no);
            return;
        }
        $this->log_result($this->logPath,"【检查订单状态,4为已付款,-2为待付款】".$orderInfo['orderStatus']);
        //已经付过
        if($orderInfo['orderStatus']>=0){
            $this->log_result($this->logPath,"【订单已支付结束】");
            echo 'success';return;
        }

        $saveData['isPay']=1;
        $saveData['orderStatus']=0;
        $saveData['paytime']=time();
        // var_dump($saveData);
        // dump($this->POSTDATA);
        //判断支付方式 1支付宝 2微信
        // $payType=$this->POSTDATA['payType']==1?1:2;
          $payType='';
        if ($orderInfo['payType'] == 4) {
            //微信购买积分商品
            $payType=4;
        }else{
             $payType=2;
        }
        // dump($payType);
        $saveData['payType']=$payType; //支付方式
        $res=M('orders')->where(array('orderId'=>$out_trade_no))->data($saveData)->save();
        // M('orders')->getLastSql();
        // dump(M('orders')->getLastSql());
        // exit();
      
        $this->log_result($this->logPath,"【更新订单数据为微信支付1修改成功0修改失败:】".$res);
        
        $userId=$orderInfo['userId'];
        // dump($orderInfo['userId']);
        if(!$userId){
            $this->log_result($this->logPath,"【用户不存在结束】");
            echo 'success';return;
        }
        $payMoney = $this->POSTDATA['total_fee']/100;
        // 验证实际支付的钱是否能订单的一致
        // if ($orderInfo['needPay']!=$payMoney) {
        //     logResult($$this->logPath, "【实际支付跟订单金额不一致】:\n" . $orderids . "\n");
        //     return;      
        // }
        $this->log_result($this->logPath,"【获取通知中的金额:】".$payMoney);
        $tradeNo = $this->POSTDATA['transaction_id'];//流水号
        $this->log_result($this->logPath,"【获取通知中的流水号:】".$tradeNo);
        $notify_time = date('Y-m-d H:i:s',strtotime($this->POSTDATA['time_end']));
        $this->log_result($this->logPath,"【获取通知中的付款时间:】".$notify_time);
        $buyer_email = $this->POSTDATA['openid']; // 买家帐号
        $this->log_result($this->logPath,"【获取通知中的付款微信id:】".$buyer_email);
        //余额减少
        // $userMoneyStatus=M('users')->where(array('userId'=>$userId))->setDec('userMoney',$payMoney);
        // file_put_contents('yuejianshaoTest','捡了几次',FILE_APPEND);
        //积分操作
        $userMoney=M('users')->where(array('userId'=>$userId))->getField('userMoney');
        // $D=$this->scoreRecord(1,$payMoney,$orderNos,1,$userId);
        $D='';
        if ($orderInfo['payType'] == 4) {
            $D=$this->scoreRecord(1,0,$orderNos,0,$userId);
        }else{
            $D=$this->scoreRecord(1,$payMoney,$orderNos,1,$userId);
        }
        $this->log_result($this->logPath,"【操作积分】:\n".$D."\n");
        $this->log_result($this->logPath,"【操作积分:】".$D);
        //付款记录
        $pr_data['payType']=$payType;//支付类型 0余额支付，1支付宝，2微信
        $pr_data['orderNo']=$orderInfo['orderNo'];
        $pr_data['payTime']=time();
        $pr_data['out_trade_no']=$out_trade_no;
        $pr_data['payMoney']=$payMoney;
        $pr_data['userId']=$userId;
        $pr_data['type']=0;
        $pr_data['notify_id']=0;
        $pr_data['notify_time']=$notify_time;
        $pr_data['buyer_email']=$buyer_email;
        $E= M('pay_record')->add($pr_data);
        // dump($E);
        $this->log_result($this->logPath,"【付款记录:】".$E);

        $mr_data ['type'] = 1;
        $mr_data ['money'] = $payMoney;
        $mr_data ['time'] = time ();
        $mr_data ['ip'] = get_client_ip ();
        // $mr_data ['orderid'] = $out_trade_no;
        $mr_data ['IncDec'] = 0;
        $mr_data ['userid'] = $userId;
        $mr_data ['balance'] = $userMoney;
        $mr_data ['remark'] = '第三方支付';
        $mr_data ['payWay'] = $payType;
        $mr_data ['orderNo'] = $orderInfo['orderNo'];
        $F = M ( 'money_record' )->add ( $mr_data );
        // dump($F);
        $this->log_result($this->logPath,"【操作支付记录:】".$F);

        //操作库存
        $order_goods=M('order_goods')->where(array('orderId'=>$out_trade_no))->select();
        $goodsDB=M('goods');

        foreach ($order_goods as $k=>$v){
             $goodsDB->where(array('goodsId'=>$v['goodsId']))->setDec('goodsStock',$v['goodsNums']);
             $goodsDB->where(array('goodsId'=>$v['goodsId']))->setInc('saleCount',$v['goodsNums']);//增加销量
        }
        // dump($res);
        //操作库存结束
        if($res){
            //订单日志记录
            $data = array();
            $data["orderId"] = $out_trade_no;
            $data["logContent"] = '付款成功';
            $data["logUserId"] = $userId;
            $data["logType"] = 0;
            $data["logTime"] = date('Y-m-d H:i:s');
            M('log_orders')->add($data);
            $this->log_result($this->logPath,"【订单日志记录】");

            //建立订单提醒
            $data = array();
            $data["orderId"] = $out_trade_no;
            $data["shopId"] = $orderInfo['shopId'];
            $data["userId"] =  $userId;
            $data["userType"] = 0;
            $data["remindType"] = 0;
            $data["createTime"] = date("Y-m-d H:i:s");
            M('order_reminds')->add($data);
            $this->log_result($this->logPath,"【建立订单提醒】");

            M()->commit();
            $this->log_result($this->logPath,"【事务提交】");
            echo 'success';return;
        }else{
            $this->log_result($this->logPath,"【事务回滚】");
            M()->rollback();
            echo 'FAIL';
            return;
        }
    }

    //余额支付
    public  function balancePay($userInfo,$orderInfo){

        $saveData['isPay']=1;
        $saveData['orderStatus']=4;
        $saveData['paytime']=time();
        M()->startTrans();
        //判断支付方式 1支付宝 2微信
        $payType=0;
        $saveData['payType']=$payType; //支付方式
        $orderStatus=M('orders')->where(array('orderId'=>$orderInfo['orderId']))->data($saveData)->save();
        $userMoneyStatus=M('users')->where(array('userId'=>$userInfo['userId']))->setDec('userMoney',$orderInfo['needPay']);

        $mr_data ['actionType'] = 1;
        $mr_data ['money'] = $orderInfo['needPay'];
        $mr_data ['time'] = time ();
        $mr_data ['ip'] = get_client_ip ();
        $mr_data ['orderid'] = $orderInfo['orderId'];
        $mr_data ['IncDec'] = 0;
        $mr_data ['userid'] = $userInfo['userId'];
        $mr_data ['balance'] = $userInfo['userMoney']-$orderInfo['needPay'];
        $mr_data ['remark'] = '余额支付';
        $mr_data ['payWay'] = 0;
        $mr_data ['orderNo'] = $orderInfo['orderNo'];
        $moneyRecordStatus = M ( 'money_record' )->add ( $mr_data );

        //操作库存
        $order_goods=M('order_goods')->where(array('orderId'=>$orderInfo['orderId']))->select();
        $goodsDB=M('goods');
        foreach ($order_goods as $k=>$v){
            $goodsDB->where(array('goodsId'=>$v['goodsId']))->setDec('goodsStock',$v['goodsNums']);
            $goodsDB->where(array('goodsId'=>$v['goodsId']))->setInc('saleCount',$v['goodsNums']);//增加销量
        }
        //操作库存结束
        if($orderStatus&&$userMoneyStatus){
            //订单日志记录
            $data = array();
            $data["orderId"] = $orderInfo['orderId'];
            $data["logContent"] = '付款成功';
            $data["logUserId"] = $userInfo['userId'];
            $data["logType"] = 0;
            $data["logTime"] = date('Y-m-d H:i:s');
            M('log_orders')->add($data);
            $this->log_result($this->logPath,"【订单日志记录】");

            //建立订单提醒
            $data = array();
            $data["orderId"] = $orderInfo['orderId'];
            $data["shopId"] = $orderInfo['shopId'];
            $data["userId"] =  $userInfo['userId'];
            $data["userType"] = 0;
            $data["remindType"] = 0;
            $data["createTime"] = date("Y-m-d H:i:s");
            M('order_reminds')->add($data);
            M()->commit();
            return true;

        }else{
            M()->rollback();
            return false;
        }
    }


    private function addMoney($out_trade_no){
        $payType=$this->POSTDATA['payType']==1?1:2;
        M()->startTrans ();
        $orderId=M('orders_payid')->where(array('orderId'=>$out_trade_no))->field('id')->select();
        $topupNo = $orderId[0]['id'];
        $isTopUp=M('top_up')->where(array('topupNo'=>$topupNo))->find();
        $status=$isTopUp['status'];
        $payMoney = $this->POSTDATA['total_fee']/100;
        $tradeNo = $this->POSTDATA['transaction_id'];//流水号
        $notify_time = date('Y-m-d H:i:s',strtotime($this->POSTDATA['time_end']));
        $buyer_email = $this->POSTDATA['openid']; // 买家帐号

        $this->log_result($this->logPath,"【充值订单ID】".$out_trade_no);
        if($status==1){
            $this->notify->setReturnParameter("return_code","SUCCESS");//设置返回码
            echo "success";exit;
        }

        $userId=$isTopUp['userid'];
        //充值表
        $A=M('top_up')->where(array('topupNo'=>$topupNo))->setField(array('status'=>1));
        $this->log_result($this->logPath,"【充值状态】".$A);
        $this->log_result($this->logPath,"【充值状态金额】".$payMoney);
        $YE=M('users')->where(array('userId'=>$userId))->getField('userMoney');//余额
        //增加余额
        $this->log_result($this->logPath,"【充值账号余额】".$YE);
        $B=M('users')->where(array('userId'=>$userId))->setInc('userMoney',$payMoney);
        $this->log_result($this->logPath,"【更新充值账号余额状态】".$B);

        //余额变动记录
        $mr_data ['type'] = 3;
        $mr_data ['money'] = $payMoney;
        $mr_data ['time'] = time ();
        $mr_data ['ip'] = get_client_ip ();
        $mr_data ['orderNo'] = $topupNo;
        $mr_data ['IncDec'] = 1;
        $mr_data ['userid'] = $userId;
        $mr_data ['balance'] = $payMoney+$YE;
        $mr_data ['remark'] = '充值到余额'.$payMoney;
        $mr_data ['payWay'] = $payType;
        // $mr_data ['orderNo'] = 0;
        $C = M ( 'money_record' )->add ( $mr_data );


        $this->log_result($this->logPath,"【余额变动记录】".$C);

        //付款记录表
        $pr_data['payType']=$payType;//支付类型 0余额支付，1支付宝，2微信
        $pr_data['orderNo']=0;
        $pr_data['payTime']=time();
        $pr_data['out_trade_no']=$out_trade_no;
        $pr_data['payMoney']=$payMoney;
        $pr_data['userId']=$userId;
        // $pr_data['type']=0;
        $pr_data['notify_id']=0;
        $pr_data['notify_time']=$notify_time;
        $pr_data['buyer_email']=$buyer_email;
        $E= M('pay_record')->add($pr_data);
        $this->log_result($this->logPath,"【付款记录】".$E);

        $this->log_result($this->logPath,"【提交】".$A.$B.$C.$E);

        if($A&&$B){
            $this->log_result($this->logPath,"【提交事务】");
            M()->commit();
            $this->notify->setReturnParameter("return_code","SUCCESS");//设置返回码
            echo 'success';exit;
        }else{
            $this->log_result($this->logPath,"【回滚事务】");
            M()->rollback();
            echo 'FAIL';
        }
    }
        // 金额操作记录
    /**
     * 构造函数
     * @param $type 操作类型,1下单，2取消订单，3充值，4提现,5订单无效
     * @param $money 金额
     * @param $orderNo 订单编号或者充值ID
     * @param $IncDec 余额变动 0为减，1加
     * @param $userid 用户ID
     * @param $balance 余额
     * @param $remark 其它备注信息
     */
    private function moneyRecord($type = '', $money = 0, $orderNo = '', $IncDec = '', $userid = 0, $balance = 0,$remark='',$payWay=0) {
        $db = M ( 'money_record' );
        $data ['actionType'] = $type;
        $data ['money'] = $money;
        $data ['time'] = time ();
        $data ['ip'] = get_client_ip ();
        $data ['orderNo'] = $orderNo;
        $data ['IncDec'] = $IncDec;
        $data ['userid'] = $userid;
        $data ['balance'] = floatval($balance)+floatval($money);
        if ($type == 1||$type == 4) {
             $data ['balance'] = floatval($balance)-floatval($money);
        }elseif ($type == 3) {
            $data ['balance'] = floatval($balance)+floatval($money);
        }
        $data ['remark'] = $remark;
        $data ['payWay'] = $payWay;
        $res = $db->add ( $data );
        // dump($data);
        // dump(M ( 'money_record' )->getLastSql());
        // dump('添加余额变动返回结果');
        // dump($res);
        return $res;
    }

// 积分操作记录
    /**
     * 构造函数
     * @param $type 1购物，2取消订单，3充值，4订单无效，5活动,6评价订单
     * @param $score 积分
     * @param $shopid 店铺ID
     * @param $orderid 订单ID或者充值ID
     * @param $IncDec 积分变动0为减，1加
     * @param $userid 用户ID payType 订单支付类型 4为积分兑换 无需变动积分，添加记录
     * @param $totalscore 用户剩余总积分
     */
    private function scoreRecord($type, $payMoney=0, $orderNo = '', $IncDec = '', $userid = 0) {
        $log_name= "Public/wx_call_back.log";//log文件路径

        $score=floatval($payMoney);
        $totalscore=M('users')->where(array('userId'=>$userid))->getField('userScore');
        $db = M ( 'score_record' );
        $data ['type'] = $type;
        $data ['time'] = time ();
        $data ['ip'] = get_client_ip ();
        $data ['orderNo'] = $orderNo;
        $data ['IncDec'] = $IncDec;
        $data ['userid'] = $userid;
        $data ['totalscore'] = $totalscore;
        $data ['score'] = $score;
        $res = $db->add ( $data );

        $this->log_result($log_name,"【积分操作记录】".$res);

        return $res;
    }
    // 支付记录
    /**
     * 构造函数
     * @param $payType 支付类型 0余额支付，1支付宝，2微信
     * @param $orderNo 订单编号
     * @param $payTime 付款时间
     * @param $out_trade_no 第三方返回的流水号
     * @param $payMoney 金额
     * @param $userId 用户ID
     * @param $type 0订单，1充值
     * @param $notify_id 通知ID
     * @param $notify_time 通知时间
     * @param $buyer_email 支付宝帐号或者微信OPENID
     * */
    private function payRecord($payType=0,$orderNo,$payTime,$out_trade_no,$payMoney,$userId,$type=0,$notify_id,$notify_time,$buyer_email){
        $data['payType']=$payType;//支付类型 0余额支付，1支付宝，2微信
        $data['orderNo']=$orderNo;
        $data['payTime']=$payTime;
        $data['out_trade_no']=$out_trade_no;
        $data['payMoney']=$payMoney;
        $data['userId']=$userId;
        $data['type']=$type;
        $data['notify_id']=$notify_id;
        $data['notify_time']=$notify_time;
        $data['buyer_email']=$buyer_email;
        $db=M('pay_record');
        $res=$db->add($data);
        // dump(M('pay_record')->getLastSql());
        // dump('添加支付记录返回结果');
        // dump($res);
        return $res;
    }

    private function log_result($file,$word){
        if($this->logPathStatus==1){
            $fp = fopen($file,"a");
            flock($fp, LOCK_EX) ;
            fwrite($fp,"日期：".strftime("%Y-%m-%d-%H:%M:%S",time()).'->'.$word."\n");
            flock($fp, LOCK_UN);
            fclose($fp);
        }
    }

}